package com.mkk.deskTopSearch.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import com.gh.deskTopSearch.file.FileData;
import com.gh.deskTopSearch.file.RealDirectory;
import com.gh.deskTopSearch.file.RealFile;
import com.gh.lucene.util.UserData;
import com.mkk.deskTopSearch.util.LogUtil;
import com.mkk.deskTopSearch.util.PageTool;
import com.mkk.deskTopSearch.util.PropertiesUtil;
import com.mkk.deskTopSearch.util.SystemUtil;
import com.mkk.deskTopSearch.worker.SearchWorker;

/**
 * 2010-8-11 上午11:25:02 搜索结果界面
 */
public class SearchResultPanel extends JPanel {

	private static final long serialVersionUID = 1L;

	// 搜索关键字
	private String keyWord;
	// 搜索结果
	private List<UserData> resList;
	// 搜索耗时
	private long times;
	// 搜索框
	private JTextField textField1;
	// 搜索按钮
	private JButton button1;
	// 显示搜索结果标签
	private JLabel label1;
	// 显示搜索结果界面
	private JPanel panel1;
	// rootBox
	private Box box1;
	// 分页按钮
	private JButton button2, button3, button4, button5;
	// 页数框
	private JTextField textField2;
	// 分页状态栏标签
	private JLabel label2;
	// 分页工具类对象
	private PageTool<UserData> pageTool;
	// 主界面对象
	private MainFrame main;
	// 每页显示的搜索结果子集
	private List<UserData> subDatas;

	/**
	 * 默认构造器
	 */
	public SearchResultPanel() {
		super();
		this.initCompents();
	}

	/**
	 * 构造器
	 * 
	 * @param keyWord
	 *            搜索关键字
	 * @param resList
	 *            搜索结果
	 * @param times
	 *            搜索耗时
	 * @param main
	 *            主界面
	 */
	public SearchResultPanel(String keyWord, List<UserData> resList,
			long times, MainFrame main) {
		super();
		this.main = main;
		this.keyWord = keyWord;
		this.resList = resList;
		this.times = times;
		this.pageTool = new PageTool<UserData>(resList,
				PropertiesUtil.DEFAULT_PAGE_SIZE);
		this.initCompents();
		this.initDatas();
		this.processEvents();
	}

	/**
	 * 初始化信息
	 */
	private void initDatas() {
		// 显示搜索结果信息
		this.setSearchResultInfo(resList.size(), times);
		this.textField1.setText(keyWord);
		// 显示分页信息
		this.setPagesInfo(this.pageTool.getTotalpages(),
				PropertiesUtil.DEFAULT_PAGE_SIZE);
		// 检查按钮可用性
		this.checkButtons();

	}

	/**
	 * 检查按钮的可用性
	 */
	private void checkButtons() {
		boolean next = this.pageTool.hasNextpage();
		boolean previ = this.pageTool.hasPreviouspage();
		this.button3.setEnabled(previ);
		this.button4.setEnabled(next);
		this.textField2.setText(String.valueOf(this.pageTool.getCurrpage()));

	}

	/**
	 * 更新界面
	 * 
	 * @param box
	 */
	private void updatePanel(Box box) {
		this.checkButtons();
		this.panel1.remove(this.box1);
		this.panel1.add(box, BorderLayout.CENTER);
		this.box1 = box;
		this.panel1.validate();
		this.panel1.repaint();
	}

	public JTextField getTextField1() {
		return textField1;
	}

	/**
	 * 事件处理
	 */
	private void processEvents() {
		// 首页事件
		this.button2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				subDatas = pageTool.getFirstpageDatas();
				Box box = getShowBoxs(subDatas);
				updatePanel(box);
			}
		});
		// 上一页事件
		this.button3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				subDatas = pageTool.getPreviouspageDatas();
				Box box = getShowBoxs(subDatas);
				updatePanel(box);
			}
		});
		// 下页事件
		this.button4.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				subDatas = pageTool.getNextpageDatas();
				Box box = getShowBoxs(subDatas);
				updatePanel(box);
			}
		});
		// 末页事件
		this.button5.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				subDatas = pageTool.getLastpageDatas();
				Box box = getShowBoxs(subDatas);
				updatePanel(box);
			}
		});
		// 自定义页码事件
		this.textField2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String s = textField2.getText().trim();
				if (s.matches("^\\d+$")) {
					int i = Integer.parseInt(s);
					if (i > 0 && i <= pageTool.getTotalpages()) {
						subDatas = pageTool.getPageDatas(i);
						Box box = getShowBoxs(subDatas);
						updatePanel(box);
					} else {
						main.setInfo("无效的页码 " + i, Color.RED);
					}
				} else {
					main.setInfo("页码必须为数字", Color.RED);
				}
			}
		});
		// 文本框焦点事件
		this.textField1.addFocusListener(new FocusAdapter() {
			public void focusGained(FocusEvent e) {
				String s = textField1.getText().trim();
				if (s.length() > 0) {
					textField1.selectAll();
				}
			}
		});
		// 搜索事件
		ActionListener listener1 = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// 1.获取搜索关键字
				String s = textField1.getText().trim();
				if (s.length() == 0) {
					main.setInfo("输入为空,不能搜索...", Color.BLUE);
					return;
				}
				try {
					main.setInfo("搜索中,请稍候...", Color.BLUE);
					// 2.提交搜索
					SearchWorker worker = new SearchWorker(s, main
							.getjProgressBar1());
					worker.execute();
					if (worker.get().equals(Boolean.TRUE)) {
						main.setInfo("搜索完成!", Color.BLUE);
						resList = worker.getResList();
						pageTool.setNewDatas(resList);
						// 更新搜索结果
						setSearchResultInfo(resList.size(), worker.getTimes());
						// 显示搜索数据
						subDatas = pageTool.getFirstpageDatas();
						Box box = getShowBoxs(subDatas);
						updatePanel(box);
						// 更新分页数据
						setPagesInfo(pageTool.getTotalpages(),
								PropertiesUtil.DEFAULT_PAGE_SIZE);
						// 检查按键
						checkButtons();
					} else {
						main.setInfo("搜索异常...", Color.RED);
						JOptionPane.showMessageDialog(main, "搜索出现异常,信息:\n"
								+ worker.getErrorInfo(), "异常",
								JOptionPane.ERROR_MESSAGE);
					}
				} catch (Exception ex) {
					main.setInfo("搜索异常...", Color.RED);
					JOptionPane.showMessageDialog(main, "搜索出现异常,信息:\n"
							+ ex.getMessage(), "异常", JOptionPane.ERROR_MESSAGE);
					ex.printStackTrace();
					// 保存异常日志
					LogUtil.saveExceptionLog(ex);
				}
			}
		};
		this.textField1.addActionListener(listener1);
		this.button1.addActionListener(listener1);

	}

	/**
	 * 搜索出的文件的点击事件
	 * 
	 * @return
	 */
	private MouseListener getFileMouseListener() {
		MouseListener ml = new MouseAdapter() {
			// 点击是打开对应的文件或文件夹
			public void mouseClicked(MouseEvent e) {
				JLabel l = (JLabel) e.getSource();
				FileData ud = getUserData(l.getText());
				if (ud != null) {
					try {
						String filePath = ud.getAbsolutePath();
						SystemUtil.openFile(filePath);
					} catch (IOException es) {
						main.setInfo("打开 " + ud.getFileName() + "异常!",
								Color.RED);
						es.printStackTrace();
						// 保存异常日志
						LogUtil.saveExceptionLog(es);
					}
				} else {
					main.setInfo(l.getText() + " 不存在...", Color.RED);
				}
			}

			public void mouseEntered(MouseEvent e) {
				JLabel l = (JLabel) e.getSource();
				main.setInfo(l.getText(), Color.GRAY);
			}

			public void mouseExited(MouseEvent e) {
				main.setInfo("欢迎使用桌面搜索系统", Color.GRAY);
			}
		};
		return ml;
	}

	/**
	 * 右键菜单点击事件
	 * 
	 * @return
	 */
	private ActionListener getItemActionListener() {
		ActionListener al = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					String ss[] = e.getActionCommand().split("@@@");
					String command = ss[0];
					String fileName = ss[1];
					FileData ud = getUserData(fileName);
					if (ud == null) {
						main.setInfo(fileName + " 不存在...", Color.RED);
						return;
					}
					String filePath = ud.getAbsolutePath();
					if ("打开".equals(command)) {
						try {
							SystemUtil.openFile(filePath);
						} catch (IOException es) {
							main.setInfo("打开 " + ud.getFileName() + "异常!",
									Color.RED);
							es.printStackTrace();
							// 保存异常日志
							LogUtil.saveExceptionLog(es);
						}
					} else if ("打开所在目录".equals(command)) {
						try {
							SystemUtil.operDir4File(filePath);
						} catch (IOException es) {
							main.setInfo("打开所在目录异常!", Color.RED);
							es.printStackTrace();
							// 保存异常日志
							LogUtil.saveExceptionLog(es);
						}
					} else if ("属性".equals(command)) {
						StringBuilder sb = new StringBuilder("<html><table>");
						sb
								.append("<tr><td><span style='color:gray'>名称:</span></td><td>"
										+ ud.getFileName() + "</td></tr>");
						sb
								.append("<tr><td><span style='color:gray'>路径:</span></td><td>"
										+ ud.getAbsolutePath() + "</td></tr>");
						if (ud instanceof RealFile) {
							RealFile rf = (RealFile) ud;
							sb
									.append("<tr><td><span style='color:gray'>文件大小:</span></td><td>"
											+ SystemUtil.formatFileLength(rf
													.getLength())
											+ "</td></tr>");
						}
						sb
								.append("<tr><td><span style='color:gray'>最后修改时间:</span></td><td>"
										+ SystemUtil.getTimeByLong(ud
												.getLastModified())
										+ "</td></tr>");
						sb
								.append("<tr><td><span style='color:gray'>是否隐藏:</span></td><td>"
										+ (ud.isHidden() ? "是" : "否")
										+ "</td></tr>");
						sb.append("</table></html>");
						JOptionPane.showMessageDialog(main, sb.toString(),
								"属性", JOptionPane.INFORMATION_MESSAGE);
					}// more else if
				} catch (Exception ex) {
					main.setInfo("操作出现异常,请重试!", Color.RED);
					ex.printStackTrace();
					// 保存异常日志
					LogUtil.saveExceptionLog(ex);
				}
			}

		};
		return al;
	}

	/**
	 * 初始化组件
	 */
	private void initCompents() {
		this.setLayout(new BorderLayout());
		// north
		this.add(this.showNorthPanel(), BorderLayout.NORTH);
		// center
		this.panel1 = this.showCenterPanel();
		this.add(new JScrollPane(panel1), BorderLayout.CENTER);
		// south
		this.add(this.showSouthPanel(), BorderLayout.SOUTH);
	}

	/**
	 * 南面面板
	 * 
	 * @return
	 */
	private JPanel showSouthPanel() {
		JPanel p = new JPanel();
		p.setLayout(new FlowLayout(FlowLayout.LEFT));
		p.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		this.button2 = new JButton("首页");
		this.button2.setToolTipText("首页");
		p.add(this.button2);
		this.button3 = new JButton("<上页");
		this.button3.setToolTipText("上页");
		p.add(this.button3);
		this.textField2 = new JTextField(3);
		this.textField2.setBorder(BorderFactory.createLoweredBevelBorder());
		this.textField2.setText("1");
		this.textField2.setBackground(Color.WHITE);
		this.textField2.setToolTipText("页码");
		p.add(this.textField2);
		this.button4 = new JButton("下页>");
		this.button4.setToolTipText("下页");
		p.add(this.button4);
		this.button5 = new JButton("末页");
		this.button5.setToolTipText("末页");
		p.add(this.button5);
		p.add(Box.createHorizontalStrut(20));
		this.label2 = new JLabel();
		p.add(this.label2);
		return p;
	}

	/**
	 * 设置分页状态栏信息
	 * 
	 * @param totalPage
	 *            总页数
	 * @param pageSize
	 *            每页显示数目
	 */
	private void setPagesInfo(int totalPage, int pageSize) {
		this.label2.setText("<html>共 <span style='color:blue'>" + totalPage
				+ "</span>页,每页显示 <span style='color:blue'>" + pageSize
				+ "</span>条结果</html>");
		this.label2.setForeground(Color.GRAY);
	}

	/**
	 * 查找指定的UserData
	 * 
	 * @param name
	 *            类似文件名
	 * @return
	 */
	private FileData getUserData(String name) {
		if (this.subDatas != null) {
			if (name.indexOf("<u>") != -1) {
				name = name.substring(name.indexOf("<u>") + 3, name
						.indexOf("</u></html>"));
			}
			for (UserData ud : subDatas) {
				if (ud instanceof FileData) {
					FileData rf = (FileData) ud;
					// 根据文件名相同来判断
					if (name.equalsIgnoreCase(rf.getFileName())) {
						return rf;
					}
				}
			}
		}
		return null;
	}

	/**
	 * 中间面板
	 * 
	 * @return
	 */
	private JPanel showCenterPanel() {
		JPanel p = new JPanel();
		p.setLayout(new BorderLayout());
		subDatas = this.pageTool.getFirstpageDatas();
		this.box1 = this.getShowBoxs(subDatas);
		p.add(this.box1, BorderLayout.CENTER);
		return p;
	}

	/**
	 * 根据当前页数据创建对应的显示组件
	 * 
	 * @param suList
	 * @return
	 */
	private Box getShowBoxs(List<UserData> suList) {
		Box box = Box.createVerticalBox();
		for (UserData ud : suList) {
			if (ud instanceof RealFile) {
				RealFile rf = (RealFile) ud;
				box.add(this.getFileBox(rf));
			} else if (ud instanceof RealDirectory) {
				RealDirectory rf = (RealDirectory) ud;
				box.add(this.getDirectoryBox(rf));
			}
		}
		// 处理数据数目不够的情况
		int len = suList.size();
		if (len < PropertiesUtil.DEFAULT_PAGE_SIZE) {
			for (int i = 0; i < (PropertiesUtil.DEFAULT_PAGE_SIZE - len); i++) {
				box.add(Box.createHorizontalStrut(60));
			}
		}
		return box;
	}

	/**
	 * 获取目录的box
	 * 
	 * @param rf
	 * @return
	 */
	private Box getDirectoryBox(RealDirectory rf) {
		Box box1 = Box.createHorizontalBox();
		box1.setBorder(BorderFactory.createLineBorder(Color.WHITE));
		JPanel p1 = new JPanel();
		p1.setLayout(new GridLayout(2, 1));
		JLabel l1 = new JLabel("<html><u>" + rf.getFileName() + "</u></html>");
		l1.setCursor(new Cursor(Cursor.HAND_CURSOR));
		l1.setFont(new Font("宋体", Font.BOLD, 12));
		l1.addMouseListener(getFileMouseListener());
		l1.setComponentPopupMenu(getDirectoryPopmenu(rf.getFileName()));
		l1.setForeground(new Color(255, 0, 1));
		l1.setToolTipText("点击打开目录 " + rf.getFileName());
		p1.add(l1);
		StringBuilder sb = new StringBuilder("<html>文件路径:");
		sb.append("<span style='color:blue'>" + rf.getAbsolutePath()
				+ "</span>   |   ");
		sb.append("最后修改时间:<span style='color:blue'>"
				+ SystemUtil.getTimeByLong(rf.getLastModified()));
		sb.append("</span></html>");
		l1 = new JLabel(sb.toString());
		p1.add(l1);
		box1.add(p1);
		return box1;
	}

	/**
	 * 获取文件的box
	 * 
	 * @param rf
	 * @return
	 */
	private Box getFileBox(RealFile rf) {
		Box box1 = Box.createHorizontalBox();
		box1.setBorder(BorderFactory.createLineBorder(Color.WHITE));
		JPanel p1 = new JPanel();
		p1.setLayout(new GridLayout(2, 1));
		JLabel l1 = new JLabel("<html><u>" + rf.getFileName() + "</u></html>");
		l1.setCursor(new Cursor(Cursor.HAND_CURSOR));
		l1.setFont(new Font("宋体", Font.BOLD, 12));
		l1.addMouseListener(this.getFileMouseListener());
		l1.setComponentPopupMenu(getFilePopmenu(rf.getFileName()));
		l1.setForeground(Color.MAGENTA);
		l1.setToolTipText("点击打开文件 " + rf.getFileName());
		p1.add(l1);
		StringBuilder sb = new StringBuilder("<html>文件路径:");
		sb.append("<span style='color:blue'>" + rf.getAbsolutePath()
				+ "</span>   |   大小:");
		sb.append("<span style='color:blue'>"
				+ SystemUtil.formatFileLength(rf.getLength())
				+ "</span>   |   ");
		sb.append("最后修改时间:<span style='color:blue'>"
				+ SystemUtil.getTimeByLong(rf.getLastModified()));
		sb.append("</span></html>");
		l1 = new JLabel(sb.toString());
		p1.add(l1);
		box1.add(p1);
		return box1;
	}

	/**
	 * 搜索出文件的右键菜单
	 * 
	 * @param fileName
	 *            文件名
	 * @return
	 */
	private JPopupMenu getFilePopmenu(String fileName) {
		JPopupMenu p = new JPopupMenu();
		JMenuItem mi = new JMenuItem("打开");
		mi.setToolTipText("打开");
		mi.setActionCommand(mi.getText() + "@@@" + fileName);
		mi.addActionListener(getItemActionListener());
		p.add(mi);
		mi = new JMenuItem("打开所在目录");
		mi.setToolTipText("打开所在目录");
		mi.setActionCommand(mi.getText() + "@@@" + fileName);
		mi.addActionListener(getItemActionListener());
		p.add(mi);
		p.addSeparator();
		mi = new JMenuItem("属性");
		mi.setToolTipText("属性");
		mi.setActionCommand(mi.getText() + "@@@" + fileName);
		mi.addActionListener(getItemActionListener());
		p.add(mi);
		return p;
	}

	/**
	 * 搜索出目录的右键菜单
	 * 
	 * @param fileName
	 * @return
	 */
	private JPopupMenu getDirectoryPopmenu(String fileName) {
		JPopupMenu p = new JPopupMenu();
		JMenuItem mi = new JMenuItem("打开");
		mi.setToolTipText("打开");
		mi.setActionCommand(mi.getText() + "@@@" + fileName);
		mi.addActionListener(getItemActionListener());
		p.add(mi);
		p.addSeparator();
		mi = new JMenuItem("属性");
		mi.setToolTipText("属性");
		mi.setActionCommand(mi.getText() + "@@@" + fileName);
		mi.addActionListener(getItemActionListener());
		p.add(mi);
		return p;
	}

	/**
	 * 北面面板
	 * 
	 * @return
	 */
	private JPanel showNorthPanel() {
		JPanel p = new JPanel();
		p.setLayout(new FlowLayout(FlowLayout.LEFT));
		p.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		this.textField1 = new JTextField(50);
		this.textField1.setToolTipText("输入搜索内容");
		this.textField1.setBackground(Color.WHITE);
		this.textField1.setBorder(BorderFactory.createLoweredBevelBorder());
		p.add(this.textField1);
		this.button1 = new JButton("搜索");
		this.button1.setToolTipText("搜索");
		p.add(this.button1);
		p.add(Box.createHorizontalStrut(20));
		this.label1 = new JLabel();
		this.label1.setFont(new Font("宋体", Font.PLAIN, 11));
		this.label1.setForeground(new Color(0, 100, 10));
		p.add(this.label1);
		return p;
	}

	/**
	 * 设置搜索结果显示信息
	 * 
	 * @param count
	 *            搜索结果数
	 * @param times
	 *            搜索耗时
	 */
	private void setSearchResultInfo(int count, long times) {
		this.label1.setText("<html>共 <span style='color:red'>" + count
				+ "</span>条结果  (用时 <span style='color:red'>"
				+ SystemUtil.formatNumber((times / 1000d), "0.00")
				+ "</span>秒)</html>");
	}

}
